<script lang="ts">
    import {
        add as add_extdata,
        CRAWLER_SERV_FILECRAWL,
        EXTDATA_TYPE_CRAWLER,
        EXTDATA_TYPE_GIT,
        EXTDATA_TYPE_MAP,
        GIT_SERV_ATOMGIT,
        GIT_SERV_GITCODE,
        update as update_extdata,
        type ExtDataInfo,
    } from "$lib/api/board/board_extdata";
    import { Modal } from "@skeletonlabs/skeleton-svelte";
    import { X } from "lucide-svelte";
    import type { Store as ToastStore } from "@zag-js/toast";
    import { getContext } from "svelte";
    import { request } from "$lib/utils/request";
    import { userStore } from "$lib/stores/user.svelte";
    import { boardStore } from "$lib/stores/board.svelte";
    import { get_self_info as atomgit_get_self_info } from "$lib/api/git_provider/atomgit/user";
    import { get_self_info as gitcode_get_self_info } from "$lib/api/git_provider/gitcode/user";
    import { openUrl } from "@tauri-apps/plugin-opener";

    const toast: ToastStore = getContext("toast");

    interface ModalProps {
        extDataInfo?: ExtDataInfo;
        onClose: () => void;
    }
    let props: ModalProps = $props();

    let name = $state(props.extDataInfo?.basic_info.name ?? "");
    let extDataType = $state(
        props.extDataInfo?.basic_info.ext_data_type ?? EXTDATA_TYPE_GIT,
    );
    let servUrl = $state(
        props.extDataInfo?.basic_info.serv_url ?? "https://api.atomgit.com",
    );
    let accessToken = $state(props.extDataInfo?.basic_info.access_token ?? "");
    let servType = $state(
        props.extDataInfo?.basic_info.serv_type ?? {
            GitServType: GIT_SERV_ATOMGIT,
        },
    );

    const canEditServUrl = $derived(() => {
        if (extDataType == EXTDATA_TYPE_CRAWLER) {
            if (servType.CrawlerServType == CRAWLER_SERV_FILECRAWL) {
                return true;
            }
        }
        return false;
    });

    async function testGitConn(): Promise<boolean> {
        if (extDataType != EXTDATA_TYPE_GIT) {
            return false;
        }
        try {
            if (servType.GitServType == GIT_SERV_ATOMGIT) {
                await atomgit_get_self_info(accessToken);
            } else if (servType.GitServType == GIT_SERV_GITCODE) {
                await gitcode_get_self_info(accessToken);
            } else {
                return false;
            }
            return true;
        } catch (e) {
            console.log(e);
            toast.create({
                title: "错误",
                description: "错误的访问令牌！",
                type: "error",
            });
            return false;
        }
    }

    async function addExtData() {
        if (extDataType == EXTDATA_TYPE_GIT) {
            const ok = await testGitConn();
            if (!ok) {
                return;
            }
        }
        await request(
            add_extdata({
                session_id: userStore.userSession,
                board_id: boardStore.curBoardId,
                basic_info: {
                    name: name,
                    ext_data_type: extDataType,
                    serv_url: servUrl,
                    access_token: accessToken,
                    serv_type: servType,
                },
            }),
        );
        toast.create({
            title: "成功",
            description: "增加外部数据源成功!",
            type: "success",
        });
        props.onClose();
    }

    async function updateExtData() {
        if (props.extDataInfo == undefined) {
            return;
        }
        if (extDataType == EXTDATA_TYPE_GIT) {
            const ok = await testGitConn();
            if (!ok) {
                return;
            }
        }
        await request(
            update_extdata({
                session_id: userStore.userSession,
                board_id: boardStore.curBoardId,
                ext_data_id: props.extDataInfo.ext_data_id,
                basic_info: {
                    name: name,
                    ext_data_type: extDataType,
                    serv_url: servUrl,
                    access_token: accessToken,
                    serv_type: servType,
                },
            }),
        );
        toast.create({
            title: "成功",
            description: "增加外部数据源成功!",
            type: "success",
        });
        props.onClose();
    }
</script>

<Modal
    open={true}
    triggerBase="btn preset-tonal"
    contentBase="card bg-surface-200-800 p-4 space-y-4 shadow-xl w-[500px]"
    backdropClasses="backdrop-blur-xs"
    backdropBase="backdrop-none"
    onOpenChange={(ev) => {
        if (!ev.open) {
            props.onClose();
        }
    }}
>
    {#snippet content()}
        <header class="flex justify-between">
            <h4 class="h4">
                {props.extDataInfo == undefined
                    ? "增加外部数据源"
                    : "修改外部数据源"}
            </h4>
            <button
                type="button"
                class="btn preset-ghost-primary-500"
                onclick={() => props.onClose()}
            >
                <X />
            </button>
        </header>

        <main class="max-h-[calc(100vh-400px)] overflow-y-auto">
            <label class="label relative p-2">
                <span class="label-text">名称</span>
                <input
                    class="input rounded-none bg-surface-100-900 text-surface-900-100"
                    type="text"
                    placeholder="请输入名称"
                    bind:value={name}
                />
            </label>
            <label class="label relative p-2">
                <span class="label-text">数据类别</span>
                <select
                    class="select rounded-none bg-surface-100-900"
                    value={extDataType}
                    disabled={props.extDataInfo != undefined}
                    onchange={(e) => {
                        const newExtDataType = parseInt(e.currentTarget.value);
                        extDataType = newExtDataType;
                        if (newExtDataType == EXTDATA_TYPE_GIT) {
                            servType = {
                                GitServType: GIT_SERV_ATOMGIT,
                            };
                            servUrl = "https://api.atomgit.com";
                        } else if (newExtDataType == EXTDATA_TYPE_CRAWLER) {
                            servType = {
                                CrawlerServType: CRAWLER_SERV_FILECRAWL,
                            };
                            servUrl = "https://api.firecrawl.dev";
                        }
                    }}
                >
                    <option value={EXTDATA_TYPE_GIT}>Git数据</option>
                    <option value={EXTDATA_TYPE_CRAWLER}>网页数据</option>
                </select>
            </label>
            {#if extDataType == EXTDATA_TYPE_GIT}
                <label class="label relative p-2">
                    <span class="label-text">GIT供应商</span>
                    <select
                        class="select rounded-none bg-surface-100-900"
                        value={servType.GitServType}
                        disabled={props.extDataInfo != undefined}
                        onchange={(e) => {
                            const newServType = parseInt(e.currentTarget.value);
                            if (newServType == GIT_SERV_ATOMGIT) {
                                servUrl = "https://api.atomgit.com";
                            } else if (newServType == GIT_SERV_GITCODE) {
                                servUrl = "https://api.gitcode.com";
                            }
                            servType = {
                                GitServType: newServType,
                            };
                        }}
                    >
                        <option value={GIT_SERV_ATOMGIT}>AtomGit</option>
                        <option value={GIT_SERV_GITCODE}>GitCode</option>
                    </select>
                </label>
            {/if}
            {#if extDataType != EXTDATA_TYPE_MAP}
                <label class="label relative p-2">
                    <span class="label-text">服务地址</span>
                    <input
                        class="input rounded-none bg-surface-100-900 text-surface-900-100"
                        type="text"
                        disabled={!canEditServUrl()}
                        value={servUrl}
                    />
                </label>
            {/if}
            <label class="label relative p-2">
                <span class="label-text">访问令牌</span>
                <input
                    class="input rounded-none bg-surface-100-900 text-surface-900-100"
                    type="password"
                    placeholder="请输入访问令牌"
                    bind:value={accessToken}
                />
                {#if extDataType == EXTDATA_TYPE_GIT}
                    <button
                        type="button"
                        class="hover:underline"
                        onclick={() => {
                            if (servType.GitServType == GIT_SERV_ATOMGIT) {
                                openUrl("https://atomgit.com/-/profile/tokens");
                            } else if (
                                servType.GitServType == GIT_SERV_GITCODE
                            ) {
                                openUrl(
                                    "https://gitcode.com/setting/token-classic/create",
                                );
                            }
                        }}>创建访问令牌</button
                    >&nbsp;(需要全部只读权限)
                {:else if extDataType == EXTDATA_TYPE_CRAWLER}
                    <button
                        type="button"
                        class="hover:underline"
                        onclick={() => {
                            if (
                                servType.CrawlerServType ==
                                CRAWLER_SERV_FILECRAWL
                            ) {
                                openUrl(
                                    "https://www.firecrawl.dev/app/api-keys",
                                );
                            }
                        }}>创建访问令牌</button
                    >
                {/if}
            </label>
        </main>
        <footer class="flex justify-end gap-4">
            <button
                type="button"
                class="btn preset-tonal"
                onclick={() => props.onClose()}>取消</button
            >
            <button
                type="button"
                class="btn preset-filled-primary-900-100"
                disabled={name.trim() == "" || accessToken.trim() == ""}
                onclick={() => {
                    if (props.extDataInfo == undefined) {
                        addExtData();
                    } else {
                        updateExtData();
                    }
                }}
            >
                {props.extDataInfo == undefined ? "增加" : "修改"}
            </button>
        </footer>
    {/snippet}
</Modal>
